﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;

namespace LpbPrj.Client.Tools.Helper
{
    public class FileHelper
    {
        /// <summary>
        /// 复制文件夹
        /// </summary>
        /// <param name="sourceFolderName">源文件夹目录</param>
        /// <param name="destFolderName">目标文件夹目录</param>
        /// <param name="overwrite">允许覆盖文件</param>
        public static void Copy(string sourceFolderName, string destFolderName, bool overwrite)
        {
            if (!Directory.Exists(sourceFolderName)) return;
            if (!Directory.Exists(destFolderName)) return;

            var sourceFilesPath = Directory.GetFileSystemEntries(sourceFolderName);

            for (int i = 0; i < sourceFilesPath.Length; i++)
            {
                var sourceFilePath = sourceFilesPath[i];
                var directoryName = Path.GetDirectoryName(sourceFilePath);
                var forlders = directoryName.Split('\\');
                var lastDirectory = forlders[forlders.Length - 1];
                var dest = Path.Combine(destFolderName, lastDirectory);

                if (File.Exists(sourceFilePath))
                {
                    var sourceFileName = Path.GetFileName(sourceFilePath);
                    if (!Directory.Exists(dest))
                    {
                        Directory.CreateDirectory(dest);
                    }
                    File.Copy(sourceFilePath, Path.Combine(dest, sourceFileName), overwrite);
                }
                else
                {
                    Copy(sourceFilePath, dest, overwrite);
                }
            }
        }

        /// <summary>
        /// 获取文件夹下的所有文件
        /// </summary>
        /// <param name="dir">路径</param>
        /// <param name="recursive">是否递归，默认不递归</param>
        /// <returns></returns>
        public static List<FileInfo> GetAllFiles(DirectoryInfo dir, bool recursive = false)
        {
            List<FileInfo> fileInfoList = new List<FileInfo>();

            FileInfo[] allFile = dir.GetFiles();
            fileInfoList.AddRange(allFile);

            if (recursive)
            {
                DirectoryInfo[] allDir = dir.GetDirectories();
                foreach (DirectoryInfo d in allDir)
                {
                    fileInfoList.AddRange(GetAllFiles(d, true));
                }
            }

            return fileInfoList;
        }


        /// <summary>
        /// 采用FileStream的形式写入数据到文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="contents"></param>
        public static void WriteAllText(string path, string contents)
        {
            using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate))
            {
                fsWrite.SetLength(0);
                if (!string.IsNullOrEmpty(contents))
                {
                    byte[] myByte = System.Text.Encoding.UTF8.GetBytes(contents);
                    fsWrite.Write(myByte, 0, myByte.Length);
                }
            };
        }

        /// <summary>
        /// 采用FileStream的形式读取文件的数据
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string ReadAllText(string path)
        {
            string contents = null;
            using (FileStream fsRead = new FileStream(path, FileMode.Open))
            {
                int fsLen = (int)fsRead.Length;
                if (fsLen > 0)
                {
                    byte[] heByte = new byte[fsLen];
                    int r = fsRead.Read(heByte, 0, heByte.Length);
                    contents = System.Text.Encoding.UTF8.GetString(heByte);
                }
            }

            return contents;
        }


        [DllImport("kernel32.dll")]

        private static extern IntPtr _lopen(string lpPathName, int iReadWrite);

        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr hObject);

        private const int OF_READWRITE = 2;
        private const int OF_SHARE_DENY_NONE = 0x40;
        private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);

        /// <summary>
        /// 判断文件是否被打开
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <returns></returns>
        public static bool FileIsOpen(string fileName)
        {
            bool isOpen = false;
            IntPtr vHandle = _lopen(fileName, OF_READWRITE | OF_SHARE_DENY_NONE);
            if (vHandle == HFILE_ERROR)
            {
                isOpen = true;
            }
            CloseHandle(vHandle);     //判断之后一定要关闭！！！
            return isOpen;
        }

    }
}
